package cn.green.mapper.model.impls.field;

import cn.green.core.model.QFieldModel;
import cn.green.mapper.model.impls.table.EntityTableMapper;
import cn.green.mapper.model.FieldColumnMapper;
import cn.green.mapper.store.EntityTableMapperStore;
import cn.green.mvc.entity.OrmTableEntity;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.util.*;

/**
 * @author wang.yishu
 * @version 1.0
 * @className OneToManyFieldColumnMapper
 * @description 一对多类型的映射
 * @date 2025/7/23 10:21
 */
@EqualsAndHashCode(callSuper = true)
@Data
public class OneToManyFieldColumnMapper extends FieldColumnMapper {

    protected Class<?> mapperClass;

    @Override
    public void setFieldValue(JSONObject row, OrmTableEntity entity) throws Exception {
        QFieldModel column = this.getColumn();
        String columnName = column.getFieldName();
        Collection<Object> fieldValue;
        Class<?> type = this.field.getType();
        if (List.class.isAssignableFrom(type)) {
            fieldValue = new ArrayList<>();
        } else if (Set.class.isAssignableFrom(type)) {
            fieldValue = new HashSet<>();
        } else {
            fieldValue = new JSONArray();
        }
        if (columnName != null && !columnName.isEmpty() && this.mapperClass != null) {
            EntityTableMapper entityTableMapper = EntityTableMapperStore.get(this.getMapperClass());
            JSONArray array = row.getJSONArray(columnName);
            if (array != null && !array.isEmpty()) {
                this.field.setAccessible(true);
                for (int i = 0; i < array.size(); i++) {
                    JSONObject object = array.getJSONObject(i);
                    if (this.mapperClass.equals(JSONObject.class)) {
                        fieldValue.add(object);
                    } else if (entityTableMapper != null) {
                        OrmTableEntity mapperEntity = entityTableMapper.toEntity(object);
                        fieldValue.add(mapperEntity);
                    }
                }
                field.set(entity, fieldValue);
            }
        }

    }

    @Override
    public void setColumnValue(JSONObject row, OrmTableEntity entity) throws Exception {
        if (this.field != null) {
            this.field.setAccessible(true);
            Object val = this.field.get(entity);
            EntityTableMapper entityTableMapper = EntityTableMapperStore.get(this.getMapperClass());
            if (val != null) {
                JSONArray json = new JSONArray();
                if (val instanceof List || val instanceof Set) {
                    JSONArray array = null;
                    if (val instanceof JSONArray) {
                        array = (JSONArray) val;
                    }
                    if (array != null) {
                        for (int i = 0; i < array.size(); i++) {
                            JSONObject object = array.getJSONObject(i);
                            if (this.mapperClass.equals(JSONObject.class)) {
                                json.add(object);
                            } else if (entityTableMapper != null) {
                                JSONObject jsonItem = entityTableMapper.toJson((OrmTableEntity) JSONObject.parseObject(object.toJSONString(), this.mapperClass));
                                json.add(jsonItem);
                            }
                        }
                    }
                }
                row.put(this.column.getFieldName(), json);
            }

        }
    }
}
